package com.hydl.power.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.hydl.power.mapper.*;
import com.hydl.power.pojo.*;
import com.hydl.power.service.OrderDeliveryService;
import com.hydl.power.utils.CalculateDistanceUtils;
import com.hydl.power.utils.IdUtil;
import com.hydl.power.utils.MessageUtils;
import com.hydl.power.utils.SmsUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.gavaghan.geodesy.Ellipsoid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**0
 * @author wxb
 * @date 2020/3/31 15:11
 */
@Service
public class OrderDeliveryServiceImpl implements OrderDeliveryService {

    @Autowired
    private OrderDeliveryMapper orderDeliveryMapper;

    @Autowired
    private OrderDeliveryMenuMapper orderDeliveryMenuMapper;

    @Autowired
    private DeviceMapper deviceMapper;

    @Autowired
    private MaintainerMapper maintainerMapper;

    @Autowired
    private ProjectMapper projectMapper;

    @Autowired
    private SysUserMapper userMapper;

    @Autowired
    private WorkOrderMapper workOrderMapper;

    @Autowired
    private MarketingMapper marketingMapper;
    @Autowired
    private ProtectDeviceMapper protectDeviceMapper;



    @Override
    public PageInfo<OrderDelivery> getOrderDelivery(Integer pageNum, Integer pageSize, Long begin, Long end, Integer orderStatus,Integer maintainerId, String areaId, String projectId, String roomId) {
        List<OrderDelivery>orderDeliveryList = orderDeliveryMapper.getOrderDelivery(pageNum, pageSize, begin, end, orderStatus,maintainerId, areaId, projectId, roomId);
        return new PageInfo<>(orderDeliveryList);
    }

    @Override
    public PageInfo<OrderDelivery> getAllOrderDeliveryTwo(Integer pageNum, Integer pageSize, String begin, String end, Integer orderStatus, Integer maintainerId, String areaId, String projectId, String roomId) {
        List<OrderDelivery>orderDeliveryList = orderDeliveryMapper.getAllOrderDeliveryTwo(pageNum, pageSize, begin, end, orderStatus,maintainerId, areaId, projectId, roomId);
        return new PageInfo<>(orderDeliveryList);
    }

    @Override
    public PageInfo<OrderDelivery> getIncidentRecord(Integer pageNum, Integer pageSize, Long begin, Long end, Integer rank, Integer faultTypes, Integer orderStatus, String roomName, String deviceName, String deviceAddress,String token) {
        if(StringUtils.isNotBlank(token)){
            SysUser user = userMapper.getUserByToken(token);
            if(user!=null){
                //k:deviceId v:deviceName
                Map<String, String> protectDeviceMap = protectDeviceMapper.selectByExample(new ProtectDeviceExample())
                    .stream()
                    .collect(Collectors.toMap(ProtectDevice::getDeviceId, ProtectDevice::getDeviceName, (a, b) -> b));
                if(user.getStatus()==2){
                    List<OrderDelivery> orderDeliveryList = orderDeliveryMapper.getIncidentRecord(pageNum, pageSize, begin, end, rank, faultTypes, orderStatus, roomName, deviceName, deviceAddress,user.getProjectId());
                    this.convertIncidentRecord(orderDeliveryList, protectDeviceMap);
                    return new PageInfo<>(orderDeliveryList);
                }else{
                    List<OrderDelivery> orderDeliveryList = orderDeliveryMapper.getIncidentRecord(pageNum, pageSize, begin, end, rank, faultTypes, orderStatus, roomName, deviceName, deviceAddress,null);
                    this.convertIncidentRecord(orderDeliveryList,protectDeviceMap);
                    return new PageInfo<>(orderDeliveryList);
                }
            }
        }
        return null;
    }
    //convert
    private void convertIncidentRecord(List<OrderDelivery> orderDeliveryList, Map<String, String> protectDeviceMap) {
        if (CollectionUtils.isEmpty(orderDeliveryList)) {
            return;
        }
        for (OrderDelivery orderDelivery : orderDeliveryList) {
            String deviceId = orderDelivery.getDeviceId();
            if (StringUtils.isBlank(deviceId)) {
                continue;
            }
            orderDelivery.setDeviceName(protectDeviceMap.getOrDefault(deviceId, orderDelivery.getDeviceName()));
        }
    }




    @Override
    public List<OrderDelivery> getList() {
        return orderDeliveryMapper.getList();
    }

    @Override
    public int updateOrderStatusById(Integer id, Integer orderStatus) {
        return orderDeliveryMapper.updateOrderStatus(id,orderStatus);
    }



    @Override
    public OrderDelivery getOrderDeliveryByfaultTime(String token) {
        if(StringUtils.isNotBlank(token)){
            SysUser user = userMapper.getUserByToken(token);
            if(user!=null){
                if(user.getStatus()==2){
                    OrderDelivery orderDelivery = orderDeliveryMapper.getOrderDeliveryByfaultTimeByProjectId(user.getProjectId());
                    return orderDelivery;
                }else{
                    return orderDeliveryMapper.getOrderDeliveryByfaultTime();
                }
            }
        }
        return null;
    }

    @Override
    public int addIncidentRecordOrderDelivery(String ids, String fault) {
        OrderDelivery orderDelivery = new OrderDelivery();
        orderDelivery.setOrderDeliveryId(IdUtil.getRandomString(8));
        orderDelivery.setOrderTypes(1);
        orderDelivery.setRank(1);
        orderDelivery.setFault(fault);
        orderDelivery.setFaultTypes(1);
        orderDelivery.setOrderStatus(1);
        orderDelivery.setFlag(1);
        orderDelivery.setFaultTime(new Date());
        Device device = deviceMapper.selectBydeviceId(ids);
      List<Marketing> marketings = marketingMapper.queryMarketingByprojectId(device.getProjectId());
      orderDelivery.setDeviceId(device.getDeviceId());
        orderDelivery.setDeviceName(device.getDeviceName());
        orderDelivery.setDeviceAddress(device.getDeviceAddress());
        orderDelivery.setSn(device.getSerialNumber());
        orderDelivery.setProjectId(device.getProjectId());
        orderDelivery.setProjectName(device.getNavId());
        orderDelivery.setRoomId(device.getPowerRoomId());
        orderDelivery.setRoomName(device.getPowerRoomName());

        orderDelivery.setAreaId(device.getAreaId());
        orderDelivery.setAreaName(device.getAreaName());
        int insert = orderDeliveryMapper.insert(orderDelivery);
        //创建工单
        WorkOrder workOrder=new WorkOrder();
        workOrder.setOrderDeliveryId(orderDelivery.getOrderDeliveryId());
        workOrder.setOrderTypes(1);
        workOrder.setRank(1);
        workOrder.setFault(fault);
        workOrder.setFaultTime(new Date());
        workOrder.setFaultTypes(1);
        workOrder.setOrderStatus(1);
        workOrder.setFlag(1);
        workOrder.setAreaId(device.getAreaId());
        workOrder.setAreaName(device.getAreaName());
        workOrder.setProjectId(device.getProjectId());
        workOrder.setProjectName(device.getNavId());
        workOrder.setRoomId(device.getPowerRoomId());
        workOrder.setRoomName(device.getPowerRoomName());
        workOrder.setDeviceId(device.getDeviceId());
        workOrder.setDeviceName(device.getDeviceName());
        workOrder.setDeviceAddress(device.getDeviceAddress());
        workOrder.setSn(device.getSerialNumber());
        workOrder.setAffirmStatus(2);
        int id=workOrderMapper.addWorkOrder(workOrder);

      for (Marketing marketing : marketings) {
        if(marketing.getStatus() == 1){
          Maintainer maintainer = maintainerMapper.selectById1(marketing.getMaintainerId());
          workOrder.setMaintainerId(Integer.parseInt(maintainer.getMaintainerId()));
          workOrder.setMaintainerName(maintainer.getName());
          workOrder.setPhone(maintainer.getPhone());
          workOrder.setDealBeginTime(new Date());
          workOrder.setOrderDeliveryTime(new Date());
          workOrder.setOrderStatus(2);
          workOrderMapper.updateWorkOrderById(workOrder);
        }
        //发送短信
        Map<String, String> map = new HashMap<String, String>();
        map.put("projectName", workOrder.getProjectName());
        map.put("powerRoomName", workOrder.getRoomName());
        map.put("deviceName", workOrder.getDeviceName());
        map.put("fault", workOrder.getFault());
        String data = JSONObject.toJSONString(map);
        SmsUtils.sendSms(marketing.getPhone(),"合一电力","SMS_196616561",data);
      }
      orderDeliveryMapper.updateOrderStatusById(3,null,null,null,workOrder.getDealBeginTime(),Integer.valueOf(workOrder.getOrderDeliveryId()));
        //自动派单
/*        Map<Double, String> distanceMap = new HashMap<>();
        List<Double> distanceList = new ArrayList<>();
        Project project = projectMapper.queryProjectByProId(device.getProjectId());
        if (WebSocketServiceImpl.locationMap.size() > 0) {
            for (Map.Entry<String, String> entry : WebSocketServiceImpl.locationMap.entrySet()) {
                Double distance = CalculateDistanceUtils.getDistance(entry.getValue(), project.getLongitudeLatitude() + "," + project.getLatitude_latitude(), Ellipsoid.Sphere);
                distanceMap.put(distance, entry.getKey());
                distanceList.add(distance);
            }
            Collections.sort(distanceList);
            for (Double distance : distanceList) {
                String maintainerId = distanceMap.get(distance);
                List<WorkOrder> orderList = workOrderMapper.getBeingProcessedOrderByMaintainerId(null, null, maintainerId);
                if (orderList.size() > 0) {
                    if (orderDelivery.getProjectId().equals(orderList.get(0).getProjectId())) {
                        workOrder.setMaintainerId(orderList.get(0).getMaintainerId());
                        workOrder.setMaintainerName(orderList.get(0).getMaintainerName());
                        workOrder.setPhone(orderList.get(0).getPhone());
                        workOrder.setDealBeginTime(new Date());
                        workOrder.setOrderDeliveryTime(new Date());
                        workOrder.setOrderStatus(2);
                        workOrderMapper.updateWorkOrderById(workOrder);
                        orderDeliveryMapper.updateOrderStatusById(3,null,null,null,workOrder.getDealBeginTime(),Integer.valueOf(workOrder.getOrderDeliveryId()));
                        break;
                    } else {
                        continue;
                    }
                } else {
                    Maintainer maintainer = maintainerMapper.selectById1(maintainerId);
                    //创建工单
                    workOrder.setMaintainerId(Integer.valueOf(maintainer.getMaintainerId()));
                    workOrder.setMaintainerName(maintainer.getName());
                    workOrder.setPhone(maintainer.getPhone());
                    workOrder.setDealBeginTime(new Date());
                    workOrder.setOrderDeliveryTime(new Date());
                    workOrder.setOrderStatus(2);
                    workOrderMapper.updateWorkOrderById(workOrder);
                    orderDeliveryMapper.updateOrderStatusById(3,null,null,null,workOrder.getDealBeginTime(),Integer.valueOf(workOrder.getOrderDeliveryId()));
                    break;
                }
            }
        }*/
        return insert;
    }

    @Override
    public ArrayList<OrderDeliveryMenu> getTree() {
        List<OrderDeliveryMenu> list = orderDeliveryMenuMapper.getAll();
        ArrayList<OrderDeliveryMenu> orderDeliveryMenuList = new ArrayList<>();
        for (OrderDeliveryMenu orderDeliveryMenu: list) {
            if(orderDeliveryMenu.getpName() == null ){
                orderDeliveryMenuList.add(orderDeliveryMenu);
            }
        }
        for (OrderDeliveryMenu orderDeliveryMenu: orderDeliveryMenuList) {
            orderDeliveryMenu.setChilds(getChild(orderDeliveryMenu.getNavId(),list) );
        }
        return orderDeliveryMenuList;
    }

    @Override
    public int updateflag(String orderDeliveryId) {
        return orderDeliveryMapper.updateFlag(orderDeliveryId);
    }


    /**
     * 批量改变告警状态
     * @param orderDeliveryIds
     * @return
     */
    @Override
    public int batchUpdateOrderStatus(String orderDeliveryIds,Integer orderStatus) {
        if(StringUtils.isNotBlank(orderDeliveryIds)){
            String[] ids = orderDeliveryIds.split(",");
            int i=orderDeliveryMapper.batchUpdateOrderStatus(ids,orderStatus);
            workOrderMapper.batchUpdateOrderStatus(ids,orderStatus);
        }

        return 0;
    }

    @Override
    public int batchUpdateOrderDelivery(String token) {
        if(StringUtils.isNotBlank(token)){
            SysUser user = userMapper.getUserByToken(token);
            if(user!=null){
                if(user.getStatus()==2){
                    orderDeliveryMapper.updateOrderStatusByProjectId(user.getProjectId());
                }else{
                    orderDeliveryMapper.updateAllOrderStatus();
                }
            }
        }
        return 0;
    }

    @Override
    public OrderDelivery getNewOrderDelivery(String token) {
        if(StringUtils.isNotBlank(token)){
            SysUser user = userMapper.getUserByToken(token);
            if(user!=null){
                if(user.getStatus()==2){
                    OrderDelivery orderDelivery = orderDeliveryMapper.getNewOrderDeliveryByProjectId(user.getProjectId());
                    return orderDelivery;
                }else{
                    OrderDelivery orderDelivery = orderDeliveryMapper.getNewOrderDeliveryByProjectId(null);
                    return orderDelivery;
                }
            }
        }
        return null;
    }

    @Override
    public OrderDelivery getOrderDelivery(String token) {
        if(StringUtils.isNotBlank(token)){
            SysUser user = userMapper.getUserByToken(token);
            if(user!=null){
                if(user.getStatus()==2){
                    OrderDelivery orderDelivery = orderDeliveryMapper.getOrderDeliveryByProjectId(user.getProjectId());
                    return orderDelivery;
                }else{
                    OrderDelivery orderDelivery = orderDeliveryMapper.getOrderDeliveryByProjectId(null);
                    return orderDelivery;
                }
            }
        }
        return null;
    }

    @Override
    public List<OrderDelivery> getOrderDeliveryByTotal(String token, Integer total) {
        if(StringUtils.isNotBlank(token)){
            SysUser user = userMapper.getUserByToken(token);
            if(user!=null){
                if(user.getStatus()==2){
                    if (user.getProjectId()!=null){
                        return  orderDeliveryMapper.getOrderDeliveryByTotal(user.getProjectId(),total);
                    }
                }else{
                    return orderDeliveryMapper.getOrderDeliveryByTotal(null,total);
                }
            }
        }
        return null;
    }

    @Override
    public Integer getOrderDeliveryTotal(String token) {
        SysUser user = userMapper.getUserByToken(token);
        if (user!=null){
            if (user.getStatus()==2){
                return orderDeliveryMapper.getOrderDeliveryTotal(user.getProjectId());
            }else {
                return orderDeliveryMapper.getOrderDeliveryTotal(null);
            }
        }
        return null;
    }


    private ArrayList<OrderDeliveryMenu> getChild(String pid, List<OrderDeliveryMenu> orderDeliveryMenuList){
        ArrayList<OrderDeliveryMenu> childs = new ArrayList<>();
        for (OrderDeliveryMenu orderDeliveryMenu: orderDeliveryMenuList) {
            if(orderDeliveryMenu.getpName() != null){
                if(orderDeliveryMenu.getpId().equals(pid)){
                    childs.add(orderDeliveryMenu);
                }
            }
        }
        for (OrderDeliveryMenu orderDeliveryMenu: childs) {
            orderDeliveryMenu.setChilds(getChild(orderDeliveryMenu.getNavId(), orderDeliveryMenuList));
        }
        if( childs.size() == 0 ){
            return null;
        }
        return childs;
    }

}


